#include "GY_MergeCellAndDragTable.h"
#include <QStandardItemModel>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QDebug>
#include <QMimeData>

GY_MergeCellAndDragTable::GY_MergeCellAndDragTable(QWidget *parent)
    : GY_IdTableView{new InSideDragStanardItemModel(this, parent), parent}
{
    EnterItemSingleSelectMode();
    QTableView::setDragEnabled(true);
    QTableView::setDefaultDropAction(Qt::DropAction::IgnoreAction);
    QTableView::setDragDropMode(QAbstractItemView::DragDropMode::DragDrop);
    setDragDropBehaviorMode(DragDropBehaviorMode::SwapSingleRow);
}

bool GY_MergeCellAndDragTable::mergeCells(const QModelIndexList &_indexList)
{
    if(_indexList.size() <= 1)
        return false;

    QModelIndexList indexList = _indexList;
    /**
     * @brief 先行排序再检查行列值是否递增最后进行合并。
     */
    // 从小到大排序
    std::sort(indexList.begin(), indexList.end());

    // 矩形合并检查
    {
        // 行连续检查
        bool bRowContinuos=true;
        QSet<int> rowSet;
        for(int i=0; i<indexList.size(); i++){
            rowSet.insert(indexList.at(i).row());
        }
        if(rowSet.count() == 1){ // 只有一行不算连续
            bRowContinuos = false;
        }else{  //  连续检查
            QList<int>rowList = rowSet.values();
            std::sort(rowList.begin(), rowList.end());

            int row=*rowList.begin();
            for(auto it=rowList.begin(); it!=rowList.end(); it++){
                if(row == *it){
                    row++;
                }else{
                    bRowContinuos=false;
                    break;
                }
            }
        }

        // 列连续检查
        bool bColContinuos=true;
        QSet<int> colSet;
        for(int i=0; i<indexList.size(); i++){
            colSet.insert(indexList.at(i).column());
        }
        if(colSet.count() == 1){ // 只有一列不算连续
            bColContinuos = false;
        }else{ // 连续检查
            QList<int>colList = colSet.values();
            std::sort(colList.begin(), colList.end());

            int col=*colList.begin();
            for(auto it=colList.begin(); it!=colList.end(); it++){
                if(col == *it){
                    col++;
                }else{
                    bColContinuos=false;
                    break;
                }
            }
        }

        if(bRowContinuos == true && bColContinuos == true){
            // 行列都连续 矩形合并
            QTableView::setSpan(indexList[0].row(), indexList[0].column(), rowSet.count(), colSet.count());
            return true;
        }else if (bRowContinuos == true && bColContinuos == false){
            // 行连续 纵向合并
            qDebug()<<__FUNCTION__<<QString::fromUtf8("纵向合并");
            QTableView::setSpan(indexList[0].row(), indexList[0].column(), rowSet.count(), 1);
            return true;
        }else if (bRowContinuos == false && bColContinuos == true){
            // 列连续 横向合并
            qDebug()<<__FUNCTION__<<QString::fromUtf8("横向合并");
            QTableView::setSpan(indexList[0].row(), indexList[0].column(), 1, colSet.count());
            return true;
        }else{
            qDebug()<<__FUNCTION__<<QString::fromUtf8("行列值不连续");
            return false;
        }
    }
}

void GY_MergeCellAndDragTable::unMergeCells(const QModelIndex &index)
{
    if(!index.isValid())return;
    QTableView::setSpan(index.row(), index.column(), 1, 1);
}

void GY_MergeCellAndDragTable::setDragDropBehaviorMode(GY_MergeCellAndDragTable::DragDropBehaviorMode mode)
{
    if(mode == DragDropBehaviorMode::Disable)
        this->setDragEnabled(false);
    else{
        this->setDragEnabled(true);
    }

    InSideDragStanardItemModel *model = dynamic_cast<InSideDragStanardItemModel*>(m_pModel);
    if(model != nullptr)
        model->m_mode = mode;
}

bool GY_MergeCellAndDragTable::mergeCells(QVariant varRowId, qint32 col, qint32 rowCount, qint32 colCount)
{
    if(col<0){
        qDebug()<<__FUNCTION__<<":"<<"col<0";
        return false;
    }
    if(rowCount <= 0 ||colCount <= 0){
        qDebug()<<__FUNCTION__<<":"<<"(rowCount<= 0 || colCounr <=0)==true";
        return false;
    }
    if(rowCount == 1 && colCount == 1){
        qDebug()<<__FUNCTION__<<":"<<"行列数都为1";
        return false;
    }

    QList<QStandardItem*> itemList = m_RowDataInfoMap.value(varRowId,{});
    if(itemList.size() == 0){
        qDebug()<<__FUNCTION__<<":"<<"rowId 不存在";
        return false;
    }

    if(col>=itemList.size()){
        qDebug()<<__FUNCTION__<<":"<<"(col<0 || col>=itemList.size()) == true";
        return false;
    }

    QModelIndex index = itemList[col]->index();
    QTableView::setSpan(index.row(), index.column(), rowCount, colCount);

    return true;
}

bool GY_MergeCellAndDragTable::mergeCells(QVariant startVarRowId, qint32 startCol, QVariant endVarRowId, qint32 endCol)
{
    if(startCol<0 || endCol<0){
        qDebug()<<__FUNCTION__<<":"<<"col<0";
        return false;
    }

    QList<QStandardItem*> startItemList = m_RowDataInfoMap.value(startVarRowId,{});
    if(startItemList.size() == 0){
        qDebug()<<__FUNCTION__<<":"<<"rowId 不存在";
        return false;
    }
    QModelIndex startIndex = startItemList[startCol]->index();

    QList<QStandardItem*> endItemList = m_RowDataInfoMap.value(endVarRowId,{});
    if(endItemList.size() == 0){
        qDebug()<<__FUNCTION__<<":"<<"rowId 不存在";
        return false;
    }
    QModelIndex endIndex = endItemList[endCol]->index();

    if(startIndex == endIndex){
        return false;
    }
    int rowSpan = abs(endIndex.row() - startIndex.row()) + 1;
    if(rowSpan==0)
        rowSpan=1;

    int colSpan = abs(endIndex.column() - startIndex.column()) + 1;
    if(colSpan==0)
        colSpan=1;

    if(startIndex < endIndex){
        QTableView::setSpan(startIndex.row(), startIndex.column(), rowSpan, colSpan);
    }else{
        QTableView::setSpan(endIndex.row(), endIndex.column(), rowSpan, colSpan);
    }


    return true;
}

void GY_MergeCellAndDragTable::unMergeCells(QVariant varRowId, qint32 col)
{
    if(col<0){
        qDebug()<<__FUNCTION__<<":"<<"col<0";
        return;
    }

    QList<QStandardItem*> itemList = m_RowDataInfoMap.value(varRowId,{});
    if(itemList.size() == 0){
        qDebug()<<__FUNCTION__<<":"<<"rowId 不存在";
        return;
    }

    QModelIndex index = itemList[col]->index();
    QTableView::setSpan(index.row(), index.column(), 1, 1);

}

void GY_MergeCellAndDragTable::keyPressEvent(QKeyEvent *event)
{
    if(event != nullptr) {
        if(event->key() == Qt::Key::Key_Control){
            EnterItemMultiSelectMode();
            return;
        }
    }
    QTableView::keyPressEvent(event);
}

void GY_MergeCellAndDragTable::keyReleaseEvent(QKeyEvent *event)
{
    if(event != nullptr) {
        if(event->key() == Qt::Key::Key_Control){
            EnterItemSingleSelectMode();
            return;
        }
    }
    QTableView::keyReleaseEvent(event);
}

void GY_MergeCellAndDragTable::EnterItemMultiSelectMode()
{
    this->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectItems);
    this->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);
}

void GY_MergeCellAndDragTable::EnterItemSingleSelectMode()
{
    this->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectItems);
    this->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
}

GY_MergeCellAndDragTable::InSideDragStanardItemModel::InSideDragStanardItemModel(QTableView *pView, QObject *parent)
    :QStandardItemModel{parent}, m_pParentView{pView}
{

}

Qt::ItemFlags GY_MergeCellAndDragTable::InSideDragStanardItemModel::flags(const QModelIndex &index) const
{
    if(index.isValid())
        return Qt::ItemFlag::ItemIsDragEnabled | Qt::ItemFlag::ItemIsDropEnabled | QStandardItemModel::flags(index);
    return QStandardItemModel::flags(index);;
}

QMimeData *GY_MergeCellAndDragTable::InSideDragStanardItemModel::mimeData(const QModelIndexList &indexes) const
{
    if(m_mode == DragDropBehaviorMode::SwapSingleRow
            || m_mode == DragDropBehaviorMode::SwapSingleCell
            || m_mode == DragDropBehaviorMode::RowInsertOnTheTarget){
        if(indexes.size() != 1){
            return nullptr;
        }

        const QModelIndex &index = indexes.at(0);
        if(m_pParentView->rowSpan(index.row(), index.column()) != 1){
            return nullptr;
        }
        if(m_pParentView->columnSpan(index.row(), index.column()) != 1){
            return nullptr;
        }

        QMimeData *data = QStandardItemModel::mimeData(indexes);
        if(data)
            data->setImageData(indexes[0]);
        return data;
    } else{
        qDebug()<<"DragDropBehaviorMode::None";
        return nullptr;
    }
}

bool GY_MergeCellAndDragTable::InSideDragStanardItemModel::dropMimeData(const QMimeData *data
                                                                        , Qt::DropAction action
                                                                        , int row, int column
                                                                        , const QModelIndex &parent)
{
    Q_UNUSED(row)
    Q_UNUSED(column)
    Q_UNUSED(action)

    qDebug()<<__FUNCTION__;
    if(data == nullptr)
        return false;

    if(m_mode == DragDropBehaviorMode::SwapSingleRow){
        //  行拖拽
        if(!parent.isValid())
            return false;

        QModelIndex oldIndex = data->imageData().value<QModelIndex>();
        if(!oldIndex.isValid())
            return false;

        int oldRow = oldIndex.row();
        int currentRow = parent.row();
        int colMax = QStandardItemModel::columnCount();
        for(int col=0; col<colMax; col++){
            QStandardItem *oldItem = takeItem(oldRow, col);
            QStandardItem *currentItem = takeItem(currentRow, col);
            // 交换两个item
            setItem(oldRow, col, currentItem);
            setItem(currentRow, col, oldItem);
        }
        return true;
    } else if(m_mode == DragDropBehaviorMode::SwapSingleCell){
        //   单元格拖拽
        if(!parent.isValid())
            return false;

        QModelIndex oldIndex = data->imageData().value<QModelIndex>();
        if(!oldIndex.isValid())
            return false;

        QModelIndex currentIndex = parent;

        QStandardItem *oldItem = takeItem(oldIndex.row(), oldIndex.column());
        QStandardItem *currentItem = takeItem(currentIndex.row(), currentIndex.column());
        // 交换两个item
        setItem(oldIndex.row(), oldIndex.column(), currentItem);
        setItem(currentIndex.row(), currentIndex.column(), oldItem);
        return true;
    }
    else if(m_mode == DragDropBehaviorMode::RowInsertOnTheTarget){
        //  行拖拽-插入到目标之上
        QModelIndex oldIndex = data->imageData().value<QModelIndex>();
        if(!oldIndex.isValid())
            return false;

        int oldRow = oldIndex.row();
        int currentRow = parent.row();
        if(oldRow == currentRow)
            return false;

        QList<QStandardItem*> itemList = QStandardItemModel::takeRow(oldRow);
        if(currentRow == -1){
            // 最后的空白处
            QStandardItemModel::appendRow(itemList);
        }
        else if(oldRow < currentRow){
            // 向下拖动
            currentRow-=1;  //  拖动行被take后目标位置上移
            QStandardItemModel::insertRow(currentRow, itemList);
        }else if(oldRow > currentRow){
            // 向上拖动
            QStandardItemModel::insertRow(currentRow, itemList);
        }
        return true;
    }
    else{
        return false;
    }

    return true;
}
